package com.kye.express.business.common_tool;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.Toast;

import com.kye.base.Logger;
import com.kye.base.utils.GsonUtils;
import com.kye.express.App;
import com.kye.express.R;
import com.kye.express.business.invoice_online.InvoiceOnlineActivity;
import com.kye.express.business.jd_reservation.list.JdReservationListActivity;
import com.kye.express.business.login.LoginActivity;
import com.kye.express.business.networkpoint_query.NetworkPointQueryActivity;
import com.kye.express.business.waybill_take_photo.WaybillTakePhotoActivity;
import com.kye.express.business.web.KyeWebActivity;
import com.kye.express.config.KyeResAction;
import com.kye.express.contract.base.BasePresenter;
import com.kye.express.contract.base.view.IView;
import com.kye.express.databinding.ActivityCommonToolBinding;
import com.kye.express.view.ToastManager;
import com.kye.model.AppDatabase;
import com.kye.model.OpenApiResultObserver;
import com.kye.model.UserSession;
import com.kye.model.base.RetrofitManager;
import com.kye.model.bean.OpenApiResult;
import com.kye.model.bean.common_tool.CommonToolItemBean;
import com.kye.model.bean.user.User;
import com.kye.model.bean.waybill_take_photo.GetIsInternalUserResultBean;
import com.kye.model.bean.waybill_take_photo.RequestGetIsInternalUserBean;
import com.kye.model.service.WaybillTakePhotoService;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.Single;
import io.reactivex.SingleEmitter;
import io.reactivex.SingleObserver;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import me.drakeet.multitype.MultiTypeAdapter;

public interface CommonToolContract {

    interface CommonToolView extends IView {

        void showLoadingPage();

        void showEmptyPage();

        void showContentPage();

        void showEditPage();

        void initSelectedDrag();

        void updateSelectedDrag(List<CommonToolItemBean> dataList);

        void showPageInit(List<CommonToolItemBean> commonToolItemBeans);

        void initContentSelectedCommonTools(List<CommonToolItemBean> commonToolItemBeans);

        void initEditSelectedCommonTools(List<CommonToolItemBean> commonToolItemBeans);

        void initEditUnselectedCommonTools(List<CommonToolItemBean> commonToolItemBeans);

        Context getContext();

        ActivityCommonToolBinding getBinding();

        int getStatusType();

        MultiTypeAdapter getSelectedAdapter();

        MultiTypeAdapter getUnselectedAdapter();
    }

    class CommonToolPresenter extends BasePresenter<CommonToolView> {

        private final static String TAG_IS_FIRST_INIT = "TAG_IS_FIRST_INIT";
        private final static String TAG_COMMON_SELECTED_TOOLS = "TAG_COMMON_SELECTED_TOOLS";
        private final static String TAG_COMMON_UNSELECTED_TOOLS = "TAG_COMMON_UNSELECTED_TOOLS";
        // 选中的常用工具缓存
        private ArrayList<CommonToolItemBean> selectedCommonTools = new ArrayList<>();
        // 没选中的常用工具缓存
        private ArrayList<CommonToolItemBean> unselectedCommonTools = new ArrayList<>();
        private boolean isFirstInit = true;

        @Override
        public void bind(CommonToolView view) {
            super.bind(view);
        }

        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (savedInstanceState != null) {
                isFirstInit = savedInstanceState.getBoolean(TAG_IS_FIRST_INIT);
                selectedCommonTools = savedInstanceState.getParcelableArrayList(TAG_COMMON_SELECTED_TOOLS);
                unselectedCommonTools = savedInstanceState.getParcelableArrayList(TAG_COMMON_UNSELECTED_TOOLS);
            }
        }

        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putBoolean(TAG_IS_FIRST_INIT, isFirstInit);
            outState.putParcelableArrayList(TAG_COMMON_SELECTED_TOOLS, selectedCommonTools);
            outState.putParcelableArrayList(TAG_COMMON_UNSELECTED_TOOLS, unselectedCommonTools);
        }

        /**
         * 1: 初始化数据, 如果首次打开初始化数据，选中和未选中的工具数据, 保证初始化数据库
         */
        public void initCommonToolsData() {
            CommonToolItemUtils.initCommonToolData()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doOnNext(new Consumer<List<CommonToolItemBean>>() {
                        @Override
                        public void accept(List<CommonToolItemBean> commonToolItemBeans) throws Exception {

                        }
                    })
                    .subscribe(new Observer<List<CommonToolItemBean>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            addDisposable(d);
                            /**
                             * show loading at the moment init
                             */
                            getView().showLoadingPage();
                        }

                        @Override
                        public void onNext(List<CommonToolItemBean> commonToolItemBeans) {
                            Logger.d("0 initCommonToolsData onNext :\n" + GsonUtils.toJsonString(commonToolItemBeans, true));
                            updateSelectedCommonTools();
                            updateUnselectedCommonTools();
                        }

                        @Override
                        public void onError(Throwable e) {
                            Logger.d("0 initCommonToolsData onError :\n" + e.getMessage());
                        }

                        @Override
                        public void onComplete() {

                        }
                    });
        }

        /**
         * 绑定选中数据
         */
        public void updateSelectedCommonTools() {
//            AppDatabase.getInstance(App.getContext())
//                    .commonToolDao()
//                    .querySelectedFlowable()
//                    .compose(getView().<List<CommonToolItemBean>>bindToLifecycleDestroy())
//                    .map(new Function<List<CommonToolItemBean>, List<CommonToolItemBean>>() {
//                        @Override
//                        public List<CommonToolItemBean> apply(List<CommonToolItemBean> commonToolItemBeans) throws Exception {
//                            Collections.sort(commonToolItemBeans, new Comparator<CommonToolItemBean>() {
//                                @Override
//                                public int compare(CommonToolItemBean o1, CommonToolItemBean o2) {
//                                    return o1.getPositionSelected() - o2.getPositionSelected();
//                                }
//                            });
//                            return commonToolItemBeans;
//                        }
//                    })
//                    .subscribeOn(Schedulers.io())
//                    .observeOn(AndroidSchedulers.mainThread())
//                    .subscribe(new Subscriber<List<CommonToolItemBean>>() {
//                        @Override
//                        public void onSubscribe(Subscription s) {
//                            s.request(Integer.MAX_VALUE);
//                        }
//
//                        @Override
//                        public void onNext(List<CommonToolItemBean> commonToolItemBeans) {
////                            Logger.d("1 updateSelectedCommonTools onNext :\n" + GsonUtils.toJsonString(commonToolItemBeans, true));
//                            selectedCommonTools = (ArrayList<CommonToolItemBean>) commonToolItemBeans;
//                            /**
//                             * todo : 处理首次加载和后续回调
//                             */
//                            if (isFirstInit) {
//                                /**
//                                 * 首次加载初始化界面状态
//                                 */
//                                getView().showPageInit(commonToolItemBeans);
//                                getView().initSelectedDrag();
//                                isFirstInit = false;
//                            } else {
//                                getView().showPageInit(commonToolItemBeans);
//                                getView().updateSelectedDrag(selectedCommonTools);
//                            }
//                        }
//
//                        @Override
//                        public void onError(Throwable t) {
//                        }
//
//                        @Override
//                        public void onComplete() {
//                        }
//                    });

            /**
             * 初始化选中的常用工具数据
             */
            Single
                    .create(new SingleOnSubscribe<List<CommonToolItemBean>>() {
                        @Override
                        public void subscribe(SingleEmitter<List<CommonToolItemBean>> e) throws Exception {
                            try {
                                List<CommonToolItemBean> selected = AppDatabase.getInstance(App.getContext())
                                        .commonToolDao()
                                        .querySelected();
                                e.onSuccess(selected);
                            } catch (Throwable t) {
                                e.onError(t);
                            }
                        }
                    })
                    .doOnSuccess(new Consumer<List<CommonToolItemBean>>() {
                        @Override
                        public void accept(List<CommonToolItemBean> commonToolItemBeans) throws Exception {
                            Collections.sort(commonToolItemBeans, new Comparator<CommonToolItemBean>() {
                                @Override
                                public int compare(CommonToolItemBean o1, CommonToolItemBean o2) {
                                    return o1.getPositionSelected() - o2.getPositionSelected();
                                }
                            });
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<List<CommonToolItemBean>>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(List<CommonToolItemBean> commonToolItemBeans) {
                            selectedCommonTools = (ArrayList<CommonToolItemBean>) commonToolItemBeans;
                            /**
                             * todo : 处理首次加载和后续回调
                             */
                            if (isFirstInit) {
                                /**
                                 * 首次加载初始化界面状态
                                 */
                                getView().showPageInit(commonToolItemBeans);
                                getView().initSelectedDrag();
                                isFirstInit = false;
                            } else {
                                getView().showPageInit(commonToolItemBeans);
                                getView().updateSelectedDrag(selectedCommonTools);
                            }
                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });
        }

        /**
         * 绑定未选中数据
         */
        public void updateUnselectedCommonTools() {
//            AppDatabase.getInstance(App.getContext())
//                    .commonToolDao()
//                    .queryUnselectedFlowable()
//                    .map(new Function<List<CommonToolItemBean>, List<CommonToolItemBean>>() {
//                        @Override
//                        public List<CommonToolItemBean> apply(List<CommonToolItemBean> commonToolItemBeans) throws Exception {
//                            Collections.sort(commonToolItemBeans, new Comparator<CommonToolItemBean>() {
//                                @Override
//                                public int compare(CommonToolItemBean o1, CommonToolItemBean o2) {
//                                    return o1.getPosition() - o2.getPosition();
//                                }
//                            });
//                            return commonToolItemBeans;
//                        }
//                    })
//                    .compose(getView().<List<CommonToolItemBean>>bindToLifecycleDestroy())
//                    .subscribeOn(Schedulers.io())
//                    .observeOn(AndroidSchedulers.mainThread())
//                    .subscribe(new Subscriber<List<CommonToolItemBean>>() {
//                        @Override
//                        public void onSubscribe(Subscription s) {
//                            s.request(Integer.MAX_VALUE);
//                        }
//
//                        @Override
//                        public void onNext(List<CommonToolItemBean> commonToolItemBeans) {
////                            Logger.d("2 updateUnselectedCommonTools onNext :\n" + GsonUtils.toJsonString(commonToolItemBeans, true));
//                            unselectedCommonTools = (ArrayList<CommonToolItemBean>) commonToolItemBeans;
//                            getView().initEditUnselectedCommonTools(commonToolItemBeans);
//                        }
//
//                        @Override
//                        public void onError(Throwable t) {
////                            Logger.d("2 updateUnselectedCommonTools onError");
//                        }
//
//                        @Override
//                        public void onComplete() {
//
//                        }
//                    });

            /**
             * 初始化未选中的常用工具数据
             */
            Single
                    .create(new SingleOnSubscribe<List<CommonToolItemBean>>() {
                        @Override
                        public void subscribe(SingleEmitter<List<CommonToolItemBean>> e) throws Exception {
                            try {
                                List<CommonToolItemBean> selected = AppDatabase.getInstance(App.getContext())
                                        .commonToolDao()
                                        .queryUnselected();
                                e.onSuccess(selected);
                            } catch (Throwable t) {
                                e.onError(t);
                            }
                        }
                    })
                    .doOnSuccess(new Consumer<List<CommonToolItemBean>>() {
                        @Override
                        public void accept(List<CommonToolItemBean> commonToolItemBeans) throws Exception {
                            Collections.sort(commonToolItemBeans, new Comparator<CommonToolItemBean>() {
                                @Override
                                public int compare(CommonToolItemBean o1, CommonToolItemBean o2) {
                                    return o1.getPosition() - o2.getPosition();
                                }
                            });
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<List<CommonToolItemBean>>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(List<CommonToolItemBean> commonToolItemBeans) {
                            unselectedCommonTools = (ArrayList<CommonToolItemBean>) commonToolItemBeans;
                            getView().initEditUnselectedCommonTools(commonToolItemBeans);
                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });
        }

        /**
         * @param item
         */
        public void onSelectedItemClicked(CommonToolItemBean item) {
            if (item != null) {
                switch (item.getId()) {
                    case 7://在线开票
                        if (UserSession.getInstance().getUser() != null && UserSession.getInstance().getUser().isLogin()) {
                            InvoiceOnlineActivity.startActivity(getView().getContext());
                        } else {
                            LoginActivity.startActivity(getView().getContext());
                        }
                        break;
                    case 8://网点查询
                        NetworkPointQueryActivity.startActivity(getView().getContext());
                        break;
                    case 9://运单拍照
                        if (UserSession.getInstance().getUser() != null && UserSession.getInstance().getUser().isLogin()) {
                            if (mIsInternalUser == -1) {
                                checkPermissionForWaybillTakePhoto();
                            } else {
                                startWaybillTakePhoto();
                            }
                        } else {
                            LoginActivity.startActivity(getView().getContext());
                        }
                        break;
                    case 10://航空违禁品
                        KyeWebActivity.startActivity(getView().getContext(), KyeResAction.AVIATION_CONTRABAND, getView().getContext().getString(R.string.aviation_contraband), false);
                        break;
                    case 11:
                        JdReservationListActivity.startActivity(getView().getContext());
                        break;
                }
            }
        }

        private void startWaybillTakePhoto() {
            if (mIsInternalUser == 0) {//不是内部同事
                WaybillTakePhotoActivity.startActivity(getView().getContext());
            } else {
                ToastManager.show(getView().getContext(), R.string.waybill_take_photo_no_permission, Toast.LENGTH_SHORT);
            }
        }

        /**
         * 删除选中项
         *
         * @param item
         */
        public void deleteSelectedCommonItem(CommonToolItemBean item) {
            item.setSelected(false);
            int addPosition = unselectedCommonTools.size();
            unselectedCommonTools.add(item);
            int removePosition = selectedCommonTools.indexOf(item);
            selectedCommonTools.remove(item);
            getView().getSelectedAdapter().setItems(selectedCommonTools);
            getView().getSelectedAdapter().notifyItemRemoved(removePosition);
            getView().getUnselectedAdapter().setItems(unselectedCommonTools);
            getView().getUnselectedAdapter().notifyItemInserted(addPosition);
        }

        /**
         * 删除未选中项
         *
         * @param item
         */
        public void deleteUnselectedCommonItem(CommonToolItemBean item) {
            item.setSelected(true);
            int addPosition = selectedCommonTools.size();
            selectedCommonTools.add(item);
            int removePosition = unselectedCommonTools.indexOf(item);
            unselectedCommonTools.remove(item);
            getView().getSelectedAdapter().setItems(selectedCommonTools);
            getView().getSelectedAdapter().notifyItemInserted(addPosition);
            getView().getUnselectedAdapter().setItems(unselectedCommonTools);
            getView().getUnselectedAdapter().notifyItemRemoved(removePosition);
        }

        public void updateCommonToolItems() {
            Observable<CommonToolItemBean> unselectedObservable = Observable.fromIterable(unselectedCommonTools)
                    .map(new Function<CommonToolItemBean, CommonToolItemBean>() {
                        @Override
                        public CommonToolItemBean apply(CommonToolItemBean commonToolItemBean) throws Exception {
                            commonToolItemBean.setPositionSelected(commonToolItemBean.getPosition());
                            return commonToolItemBean;
                        }
                    });
            Observable<CommonToolItemBean> selectedObservable = Observable.fromIterable(selectedCommonTools)
                    .map(new Function<CommonToolItemBean, CommonToolItemBean>() {
                        @Override
                        public CommonToolItemBean apply(CommonToolItemBean commonToolItemBean) throws Exception {
                            int position = selectedCommonTools.indexOf(commonToolItemBean);
                            commonToolItemBean.setPositionSelected(position);
                            return commonToolItemBean;
                        }
                    });
            Observable.concat(selectedObservable, unselectedObservable)
                    .toList()
                    .map(new Function<List<CommonToolItemBean>, List<Long>>() {
                        @Override
                        public List<Long> apply(List<CommonToolItemBean> commonToolItemBeans) throws Exception {
                            return AppDatabase.getInstance(getView().getContext())
                                    .commonToolDao().insertAll(commonToolItemBeans);
                        }
                    })
                    .doOnSuccess(new Consumer<List<Long>>() {
                        @Override
                        public void accept(List<Long> longs) throws Exception {
//                            Logger.d("doOnSuccess : ids \n" + GsonUtils.toJsonString(longs, true));
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<List<Long>>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(List<Long> longs) {

                        }

                        @Override
                        public void onError(Throwable e) {
//                            Logger.d("onError : " + e.getMessage());
                        }
                    });
        }

        /**
         * 更新拖拽顺序
         *
         * @param dataList
         */
        public void updateSelectedPosition(final List<CommonToolItemBean> dataList) {
            Observable.fromIterable(dataList)
                    .map(new Function<CommonToolItemBean, CommonToolItemBean>() {
                        @Override
                        public CommonToolItemBean apply(CommonToolItemBean commonToolItemBean) throws Exception {
                            int selectedPosition = dataList.indexOf(commonToolItemBean);
                            commonToolItemBean.setPositionSelected(selectedPosition);
                            return commonToolItemBean;
                        }
                    })
                    .doOnNext(new Consumer<CommonToolItemBean>() {
                        @Override
                        public void accept(CommonToolItemBean commonToolItemBean) throws Exception {
                            Logger.d("updateSelectedPosition >>> : \n" + GsonUtils.toJsonString(commonToolItemBean, true));
                        }
                    })
                    .toList()
                    .map(new Function<List<CommonToolItemBean>, List<Long>>() {
                        @Override
                        public List<Long> apply(List<CommonToolItemBean> commonToolItemBeans) throws Exception {
                            return AppDatabase.getInstance(getView().getContext())
                                    .commonToolDao().insertAll(commonToolItemBeans);
                        }
                    })
                    .doOnSuccess(new Consumer<List<Long>>() {
                        @Override
                        public void accept(List<Long> longs) throws Exception {
                            Logger.d("doOnSuccess : ids \n" + GsonUtils.toJsonString(longs, true));
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<List<Long>>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(List<Long> longs) {

                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });


        }

        public Single<List<CommonToolItemBean>> getInitContentSelectedDataSingle(List<CommonToolItemBean> commonToolItemBeans) {
            return
                    Observable.fromIterable(commonToolItemBeans)
                            .map(new Function<CommonToolItemBean, CommonToolItemBean>() {
                                @Override
                                public CommonToolItemBean apply(CommonToolItemBean commonToolItemBean) throws Exception {
                                    commonToolItemBean.setShowSelectedIcon(false);
                                    return commonToolItemBean;
                                }
                            })
                            .toList()
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread());
        }

        public Single<List<CommonToolItemBean>> getInitEditSelectedDataSingle(List<CommonToolItemBean> commonToolItemBeans) {
            return
                    Observable.fromIterable(commonToolItemBeans)
                            .map(new Function<CommonToolItemBean, CommonToolItemBean>() {
                                @Override
                                public CommonToolItemBean apply(CommonToolItemBean commonToolItemBean) throws Exception {
                                    commonToolItemBean.setShowSelectedIcon(true);
                                    return commonToolItemBean;
                                }
                            })
                            .toList()
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread());
        }

        public Single<List<CommonToolItemBean>> getInitEditUnselectedDataSingle(List<CommonToolItemBean> commonToolItemBeans) {
            return
                    Observable.fromIterable(commonToolItemBeans)
                            .map(new Function<CommonToolItemBean, CommonToolItemBean>() {
                                @Override
                                public CommonToolItemBean apply(CommonToolItemBean commonToolItemBean) throws Exception {
                                    commonToolItemBean.setShowSelectedIcon(true);
                                    return commonToolItemBean;
                                }
                            })
                            .toList()
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread());
        }

        public ArrayList<CommonToolItemBean> getSelectedCommonTools() {
            return selectedCommonTools;
        }

        public ArrayList<CommonToolItemBean> getUnselectedCommonTools() {
            return unselectedCommonTools;
        }

        private int mIsInternalUser = -1;//-1:表示还没请求过，1：表示是内部同事，0：表示不是内部同事

        /**
         * 检测是否有权限进入运单拍照
         */
        public void checkPermissionForWaybillTakePhoto() {
            String phone = "";
            User user = UserSession.getInstance().getUser();
            if (user != null) {
                phone = user.getPhone();
            }

            RetrofitManager.getInstance().createOpenApiService(WaybillTakePhotoService.class)
                    .getIsInternalUser(new RequestGetIsInternalUserBean(phone))
                    .compose(getView().<OpenApiResult<GetIsInternalUserResultBean>>bindToLifecycleDestroy())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new OpenApiResultObserver<GetIsInternalUserResultBean>() {

                        @Override
                        public void onLoading(Disposable d) {
                            //getView().onLoading();
                        }

                        @Override
                        public void onOtherError(Throwable e) {
                        }

                        @Override
                        public void onLoaded() {
                        }

                        @Override
                        public void onSuccess(OpenApiResult<GetIsInternalUserResultBean> result, GetIsInternalUserResultBean datas) {
                            if (datas != null) {
                                mIsInternalUser = datas.getType();
                                startWaybillTakePhoto();
                            }
                        }

                        @Override
                        public void onApiError(OpenApiResult<GetIsInternalUserResultBean> result, int code, String msg) {

                        }
                    });
        }

    }
}
